/* *
 * @file    audio_player.c
 * @author  Azolla (1228449928@qq.com)
 * @brief   audio play mp3 file
 * @version 0.1
 * @date    2022-11-04
 * 
 * @copyright Copyright (c) 2022
 * */
#include <string.h>
#include "dirent.h" 

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h" 
#include "freertos/semphr.h" 
#include "esp_log.h"
#include "sdkconfig.h"

#include "audio_i2s.h" 
#include "audio_spiffs.h"  
#include "audio_player.h"
#include "wav_decoder.h"
 
static const char *TAG = "audio_player";
 
static QueueHandle_t xQueue = NULL;   
 
int audio_music_play(uint32_t findex)
{
    return xQueueSend(xQueue, &findex, (TickType_t)0);   
}

void audio_paly_task(void *arg)
{
    uint32_t findex = 0;
    int8_t audio_data[AUDIO_I2S_BUFF_SIZE];
    while ( true ) {
        if (xQueueReceive(xQueue, &findex, portMAX_DELAY) == pdTRUE) { 
            size_t fsize;
            FILE *fb = spiffs_open_file(findex, &fsize);
            if (fb == NULL) continue;
            ESP_LOGI(TAG, "file_fsize: %d", fsize);
            while ( true ) {
                size_t size = fread(audio_data, sizeof(uint8_t), AUDIO_I2S_BUFF_SIZE, fb);
                if (size > 0) {
                    audio_i2s_write(audio_data, size);
                }
                if (size < AUDIO_I2S_BUFF_SIZE) {  // read fail or over.
                    break;
                }
            }
            fclose(fb);  // Remember to close file.
        } 
    }
    vTaskDelete(NULL);
}


void audio_player_init(void)
{  
    audio_i2s_init();
 
    audio_spiffs_init();
  
    audio_set_volume(100);  // set volume: 10%

    xQueue = xQueueCreate(2, sizeof(uint32_t));

    xTaskCreatePinnedToCore(audio_paly_task, "audio_paly", 4 * 1024, NULL, 8, NULL, APP_CPU_NUM); 
 
    // audio_music_play(0);
    // vTaskDelay(3000);
 
#if 0  // wav 解码
    void *wav_decoder = NULL;
    const char *wav_file = "/spiffs/power_on.wav";
    wav_decoder = wav_decoder_open(wav_file);

    if (wav_decoder == NULL) {
        printf("can not find %s, play next song\n", wav_file);
    } else {
        int channels = wav_decoder_get_channel(wav_decoder);
        int sample_rate = wav_decoder_get_sample_rate(wav_decoder);
        printf("start to play %s, channels:%d, sample rate:%d \n", wav_file, channels, sample_rate );
    }
    
    unsigned char* buffer = malloc(AUDIO_I2S_BUFF_SIZE * sizeof(unsigned char));
 
    while (1) {
        int size = wav_decoder_run(wav_decoder, buffer, AUDIO_I2S_BUFF_SIZE);
        audio_i2s_write(buffer, size);
        // ESP_LOGI(TAG, "wav_decoder_run: %d", size);
        if (size < AUDIO_I2S_BUFF_SIZE) {
            memset(buffer + size, 0, AUDIO_I2S_BUFF_SIZE - size);
            wav_decoder_close(wav_decoder);
            wav_decoder = NULL;
            break;
        }
    }
#endif

#if 0 // test...
    while (1) {
        vTaskDelay(3000);
        static uint8_t dir = 0; printf("audio_music_play = %d\n", dir);
        audio_music_play(dir);
        if (++dir > 7) {
            dir = 0;
            static uint8_t value = 0;
            if (value > 10) value = 10;
            else value = 50;
            audio_music_set_volume(value);
        } 
        vTaskDelay(1000);
    }
#endif    
}
